﻿//But at least one issue is left: very slow yet

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// 
    /// </summary>
    public class Lines45Degrees : BaseImageFilter
    {
        protected int m_nThreshold = 10;
        protected DIRECTION_MODE M_MODE = DIRECTION_MODE.BOTH;

        /// <summary>
        /// Initializes a new instance of the <see cref="Lines45Degrees"/> class.
        /// </summary>
        public Lines45Degrees()
        {
        }

        /// <summary>
        /// Gets or sets the MODE.
        /// </summary>
        /// <value>The MODE.</value>
        public DIRECTION_MODE MODE
        {
            get { return M_MODE; }
            set { M_MODE = value; }
        }

        /// <summary>
        /// Gets or sets the threshold.
        /// </summary>
        /// <value>The threshold.</value>
        public int Threshold
        {
            get { return m_nThreshold; }
            set { m_nThreshold = value; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Lines45Degrees"/> class.
        /// </summary>
        /// <param name="_lines45Degrees">The _lines45 degrees.</param>
        internal Lines45Degrees(Lines45Degrees _lines45Degrees)
        {
            m_nThreshold = _lines45Degrees.m_nThreshold;
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            UnsafeBitmap bitmap = _bitmap;

            UnsafeBitmap bitmapCloned = (UnsafeBitmap)_bitmap.Clone();

            int nHeight = _bitmap.Height;
            int nWidth = _bitmap.Width;

            int x = 0;
            int y = 0;

            Color color1stRowLeft = Color.Transparent;
            Color color2ndRowLeft = Color.Transparent;
            Color color1stRowRight = Color.Transparent;
            Color color2ndRowRight = Color.Transparent;

            if (M_MODE == DIRECTION_MODE.BOTH || M_MODE == DIRECTION_MODE.HORIZONTAL)
            {
                for (y = 0; y < nHeight; y++)
                {

                    for (x = 0; x < nWidth; x++)
                    {
                        if (x + 1 > nWidth - 1 && y + 1 > nHeight - 1)
                        {
                            continue;
                        }
                        color1stRowLeft = bitmapCloned.GetPixel(x, y);
                        color2ndRowLeft = bitmapCloned.GetPixel(x + 1, y + 1);

                        int nDist1 = ColorFunctions.DistanceSquared(color1stRowLeft, color2ndRowLeft);
                        bitmap.SetPixel(x, y, nDist1 < m_nThreshold ? Definitions.White : Definitions.Black);
                    }
                }
            }

            if (M_MODE == DIRECTION_MODE.BOTH || M_MODE == DIRECTION_MODE.VERTICAL)
            {
                for (y = 0; y < nHeight; y++)
                {

                    for (x = 0; x < nWidth; x++)
                    {
                        if (x + 1 > nWidth - 1 && y + 1 > nHeight - 1)
                        {
                            continue;
                        }
                        color1stRowRight = bitmapCloned.GetPixel(nWidth - x - 1, y);
                        color2ndRowRight = bitmapCloned.GetPixel(nWidth - x - 1 - 1, y + 1);

                        int nDist2 = ColorFunctions.DistanceSquared(color1stRowRight, color2ndRowRight);
                        bitmap.SetPixel(x, y, nDist2 < m_nThreshold ? Definitions.White : Definitions.Black);
                    }
                }
            }


            return _bitmap;
        }

        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new Lines45Degrees(this);
        }
    }
}
